<?php

namespace app\shop\controller\product;

use think\Controller;

class Order extends Controller
{
    protected $BusinessModel;
    protected $AddressModel;
    protected $CartModel;
    protected $ReceiveModel;
    protected $ProductModel;
    protected $OrderModel;
    protected $OrderProductModel;
    protected $RecordModel;
    protected $CommissionModel;
    protected $ProductTopModel;

    public function __construct()
    {
        parent::__construct();

        $this->BusinessModel = model('business.Business');
        $this->AddressModel = model('business.Address');
        $this->CartModel = model('product.Cart');
        $this->ReceiveModel = model('coupon.Receive');
        $this->ProductModel = model('product.Product');
        $this->OrderModel = model('product.order.Order');
        $this->OrderProductModel = model('product.order.Product');
        $this->RecordModel = model('business.Record');
        $this->CommissionModel = model('business.Commission');
        $this->ProductTopModel = model('product.Top');
    }

    //地址设置
    public function address()
    {
        if ($this->request->isAjax()) {
            $busid = $this->request->param('busid', 0, 'trim');

            $business = $this->BusinessModel->find($busid);

            if (!$business) {
                $this->error('用户不存在');
            }

            $business = $this->AddressModel->where(['busid' => $busid, 'status' => 1])->find();

            if (!$business) {
                $this->error($this->AddressModel->getError());
            }

            $this->success("查询地址成功", null, $business);
        }
    }

    // 获取优惠券数据
    public function coupon()
    {
        if ($this->request->isPost()) {
            $busid = $this->request->param('busid', 0, 'trim');

            $business = $this->BusinessModel->find($busid);

            if (!$business) {
                $this->error('用户不存在');
            }

            $CouponList = $this->ReceiveModel->with(['coupon'])->where(['busid' => $busid])->select();

            if ($CouponList) {
                $this->success('查询优惠券成功', null, $CouponList);
            } else {
                $this->error('暂无优惠券');
            }
        }
    }

    // 确认订单页面获取相应购物车的数据
    public function cart()
    {
        if ($this->request->isPost()) {
            $busid = $this->request->param('busid', 0, 'trim');
            $cartids = $this->request->param('cartids', 0, 'trim');

            $business = $this->BusinessModel->find($busid);

            if (!$business) {
                $this->error('用户不存在');
            }

            $CartList = $this->CartModel->with(['product'])->where(['cart.id' => ['IN', $cartids]])->select();

            if ($CartList) {
                $this->success('查询购物车记录成功', null, $CartList);
            } else {
                $this->error('暂无购物车记录');
            }
        }
    }

    //提交订单
    public function add()
    {
        if ($this->request->isPost()) {
            $busid = $this->request->param('busid', 0, 'trim');
            $addrid = $this->request->param('addrid', 0, 'trim');
            $cartids = $this->request->param('cartids', 0, 'trim');
            $couponid = $this->request->param('couponid', 0, 'trim');
            $pay = $this->request->param('pay', 'money', 'trim');
            $remark = $this->request->param('remark', 0, 'trim');

            $business = $this->BusinessModel->find($busid);
            $address = $this->AddressModel->find($addrid);
            $CartList = $this->CartModel->with(['product'])->where(['cart.id' => ['IN', $cartids]])->select();

            if (!$business) {
                $this->error('用户不存在');
            }
            if (!$address) {
                $this->error('地址不存在');
            }
            if (!$CartList) {
                $this->error('商品订单不存在');
            }

            // 该订单总价
            $total = 0;

            foreach ($CartList as $item) {
                if ($item['nums'] > $item['product']['stock']) {
                    $this->error("{$item['product']['name']}库存不足");
                }

                $total += (float)$item['total'];
            }

            // 根据用户领取优惠券id查询该优惠券是否使用
            $coupon = $this->ReceiveModel->with(['coupon'])->where(['busid' => $busid, 'cid' => $couponid, 'receive.status' => '1'])->find();

            if ($coupon) {
                $rate = $coupon['coupon']['rate'];
            } else {

                $rate = 1;
            }

            $total = bcmul($total, $rate, 2);

            if ($pay === 'money') {
                $updateMoney = bcsub($business['money'], $total, 2);
                if ($updateMoney < 0) {
                    $this->error("余额不足，请尽快充值");
                }

                //对多个数据进行操作，就要开启事务
                /* 
                    新增订单记录
                    新增订单商品关联记录
                    更新用户余额
                    更新优惠券状态
                    更新商品库存
                    新增消费记录
                    新增佣金记录
                    删除购物车记录
                */

                // 开启事务
                $this->OrderModel->startTrans();
                $this->OrderProductModel->startTrans();
                $this->BusinessModel->startTrans();
                $this->ReceiveModel->startTrans();
                $this->ProductModel->startTrans();
                $this->RecordModel->startTrans();
                $this->CommissionModel->startTrans();
                $this->CartModel->startTrans();

                // 封装订单数据
                $OrderData = [
                    'code' => build_code('SP'),     //订单号
                    'busid' => $busid,             //用户id
                    'businessaddrid' => $addrid,     //收货地址id
                    'amount' => $total,         //总金额
                    'remark' => $remark,           //备注
                    'status' => 1,             //已支付
                    'pay' => $pay             //用什么支付
                ];

                // 是否使用
                if ($coupon && $coupon['status'] == 1) {
                    $OrderData['couponid'] = $couponid;

                    $CouponData = [
                        'id' => $couponid,
                        'status' => '0'
                    ];

                    // 更新优惠券状态
                    $CouponStatus = $this->ReceiveModel->isUpdate(true)->save($CouponData);

                    if ($CouponStatus === false) {
                        $this->error('更新优惠券状态失败');
                    }
                }

                $OrderStatus = $this->OrderModel->validate('common/product/order/Order')->save($OrderData);

                if ($OrderStatus === false) {
                    $this->ReceiveModel->rollback();
                    $this->error($this->OrderModel->getError());
                }

                // 订单商品数据
                $OrderProductData = [];

                // 商品数据
                $ProductData = [];

                //商品榜单
                $PorductTop = [];

                // 循环
                foreach ($CartList as $item) {

                    $OrderProductData[] = [
                        'orderid' => $this->OrderModel->id,
                        'busid' => $busid,
                        'proid' => $item['product']['id'],
                        'pronum' => $item['nums'],
                        'price' => $item['price'],
                        'total' => $item['total'],
                        'attrs' => $item['attrs']
                    ];

                    $ProductData[] = [
                        'id' => $item['proid'],
                        'stock' => bcsub($item['product']['stock'], $item['nums'])
                    ];
                }

                // halt(collection($CartList)->toArray());
                //对多个数据进行表操作，要使用saveAll来操作保存
                $OrderProductStatus = $this->OrderProductModel->validate('common/product/order/Product')->saveAll($OrderProductData);

                if ($OrderProductStatus === false) {
                    // ‌由于某种原因需要撤销更改，‌可以使用rollback()方法来实现。‌这个操作会撤销事务中所有未提交的更改，‌使数据库恢复到事务开始前的状态。‌
                    $this->OrderModel->rollback();
                    $this->ReceiveModel->rollback();
                    $this->error($this->OrderProductModel->getError());
                }

                // 更新商品库存
                $ProductStatus = $this->ProductModel->isUpdate(true)->saveAll($ProductData);

                if ($ProductStatus === false) {
                    $this->OrderModel->rollback();
                    $this->ReceiveModel->rollback();
                    $this->OrderProductModel->rollback();
                    $this->error('更新商品库存失败');
                } else {
                    foreach ($CartList as $item) {
                        //榜单排行
                        $PorductTop = [];

                        $ProTop = $this->ProductTopModel->where(['proid' => $item['proid']])->select();

                        if (!$ProTop) {
                            $PorductTop['proid'] = $item['proid'];
                            $PorductTop['nums'] = $item['nums'];
                            $ProTops =  $this->ProductTopModel->validate('common/product/Top')->save($PorductTop);
                            if (!$ProTops) {
                                $this->error("销量排行保存失败");
                            }
                        } else {
                            $num = bcadd($ProTop[0]['nums'], $item['nums']);
                            $PorductTop = [
                                'nums' => intval($num)
                            ];
                            // halt($PorductTop);
                            $ProTops =  $this->ProductTopModel->where(['proid' => $item['proid']])->update($PorductTop);
                        }

                        if (!$ProTops) {
                            $this->error("销量排行更新失败");
                        }
                    }
                }

                // 消费记录
                $RecordData = [
                    'total' => "-{$total}",           //消费金额，负数为消费，正数为充值
                    'busid' => $busid,
                    'content' => "商城订单号：{$OrderData['code']}，消费了{$total}元"
                ];

                $RecordStatus = $this->RecordModel->validate('common/business/Record')->save($RecordData);

                if ($RecordStatus === false) {
                    $this->OrderModel->rollback();
                    $this->ReceiveModel->rollback();
                    $this->OrderProductModel->rollback();
                    $this->ProductModel->rollback();
                    $this->error($this->RecordModel->getError());
                }

                // 更新用户余额
                $BusinessData = [
                    'id' => $busid,
                    'money' => $updateMoney
                ];

                //手写验证器
                $BusinessValidate = [
                    [
                        'id' => 'require',
                        'money' => 'require|>=:0'
                    ],
                    [
                        'id.require' => '用户id未知',
                        'money.require' => '用户余额必填',
                        'money.>:' => '用户余额大于等于0'
                    ]
                ];

                $BusinessStatus = $this->BusinessModel->validate(...$BusinessValidate)->update($BusinessData);

                if ($BusinessStatus === false) {
                    $this->OrderModel->rollback();
                    $this->ReceiveModel->rollback();
                    $this->OrderProductModel->rollback();
                    $this->ProductModel->rollback();
                    $this->RecordModel->rollback();
                    $this->error($this->BusinessModel->getError());
                }

                // 佣金
                $parentid = $business['parentid'] ?? 0;

                $parent = $this->BusinessModel->find($parentid);

                if ($parent) {
                    // 佣金比率
                    $AmountRate = config('site.AmountRate');

                    // 组装佣金记录
                    $CommissionData = [
                        'orderid' => $this->OrderModel->id,
                        'busid' => $busid,
                        'parentid' => $parentid,
                        'amount' => bcmul($total, $AmountRate, 2),
                        'type' => 'product',
                        'status' => 0,
                    ];
                    //保存佣金到数据库
                    $CommissionStatus = $this->CommissionModel->validate('common/business/Commission')->save($CommissionData);

                    if ($CommissionStatus === false) {
                        $this->OrderModel->rollback();
                        $this->ReceiveModel->rollback();
                        $this->OrderProductModel->rollback();
                        $this->ProductModel->rollback();
                        $this->RecordModel->rollback();
                        $this->BusinessModel->rollback();
                        $this->error($this->CommissionModel->getError());
                    }
                }

                // 删除购物车记录
                $CartStatus = $this->CartModel->destroy($cartids);

                if ($CartStatus === false) {
                    $this->OrderModel->rollback();
                    $this->ReceiveModel->rollback();
                    $this->OrderProductModel->rollback();
                    $this->ProductModel->rollback();
                    $this->RecordModel->rollback();
                    $this->BusinessModel->rollback();
                    $this->CommissionModel->rollback();

                    $this->error('删除购物车记录失败');
                }

                if ($OrderStatus === false || $OrderProductStatus === false || $ProductStatus === false || $BusinessStatus === false || $RecordStatus === false || $CartStatus === false) {
                    $this->OrderModel->rollback();
                    $this->ReceiveModel->rollback();
                    $this->OrderProductModel->rollback();
                    $this->ProductModel->rollback();
                    $this->RecordModel->rollback();
                    $this->BusinessModel->rollback();
                    $this->CommissionModel->rollback();
                    $this->CartModel->rollback();

                    $this->error('支付失败');
                } else {
                    $this->OrderModel->commit();
                    $this->ReceiveModel->commit();
                    $this->OrderProductModel->commit();
                    $this->ProductModel->commit();
                    $this->RecordModel->commit();
                    $this->BusinessModel->commit();
                    $this->CommissionModel->commit();
                    $this->CartModel->commit();
                    $this->ProductTopModel->commit();

                    $this->success('支付成功');
                }
            }
        }
    }

    //直接购买提交订单
    public function info()
    {
        if ($this->request->isPost()) {
            $busid = $this->request->param('busid', 0, 'trim');
            $orderid = $this->request->param('orderid', 0, 'trim');

            $business = $this->BusinessModel->find($busid);

            if (!$business) {
                $this->error('用户不存在');
            }
            $order = $this->OrderModel->with(['orderProduct' => ['products'], 'address'])->where(['order.id' => $orderid])->find();

            if ($order) {
                $this->success('查询订单详情成功', null, $order);
            } else {
                $this->error('订单不存在');
            }
        }
    }

    //全部订单的懒加载
    public function index()
    {
        if ($this->request->isPost()) {
            $busid = $this->request->param('busid', 0, 'trim');
            $page = $this->request->param('page', 1, 'trim');
            $status = $this->request->param('status', 0, 'trim');

            $business = $this->BusinessModel->find($busid);

            if (!$business) {
                $this->error('用户不存在');
            }

            // 条件数组
            $where = [
                'busid' => $busid
            ];

            if ($status > 0) {
                $where['status'] = $status;
            } else if ($status < 0) {
                $where['status'] = ['<', $status];
            }

            $orderList = $this->OrderModel->where($where)->order('createtime desc')->page($page, 10)->select();

            $count = $this->OrderModel->where($where)->count();

            $data = [
                'list' => $orderList,
                'count' => $count
            ];

            if ($orderList) {
                // 获取订单里的其中一个商品
                foreach ($orderList as $item) {
                    $item['info'] = $this->OrderProductModel->with(['products'])->where(['orderid' => $item['id']])->find();
                }

                $this->success('查询订单数据成功', null, $data);
            } else {
                $this->error('暂无订单', null, $data);
            }
        }
    }

    //确认收货
    public function confirm()
    {
        if ($this->request->isPost()) {
            $busid = $this->request->param('busid', 0, 'trim');
            $orderid = $this->request->param('orderid', 0, 'trim');
            $status = $this->request->param('status', 0, 'trim');

            $business = $this->BusinessModel->find($busid);

            if (!$business) {
                $this->error('用户不存在');
            }

            $Order = $this->OrderModel->find($orderid);

            if (!$Order) {
                $this->error("订单不存在");
            }

            $updateOrder = $this->OrderModel->isUpdate(true)->save(['id' => $orderid, 'status' => $status]);

            if ($updateOrder) {
                $this->success("收货成功");
            } else {
                $this->error("收货失败");
            }
        }
    }

    //评论页面的商品显示接口
    public function orderCt()
    {
        if ($this->request->isPost()) {
            $busid = $this->request->param('busid', 0, 'trim');
            $orderid = $this->request->param('orderid', 0, 'trim');

            $business = $this->BusinessModel->find($busid);

            if (!$business) {
                $this->error('用户不存在');
            }

            $order = $this->OrderProductModel->with(['products'])->where(['orderid' => $orderid, 'busid' => $busid])->select();


            if ($order) {
                $this->success('查找成功', null, $order);
            } else {
                $this->error('查找失败');
            }
        }
    }
}
